package com.wuliu.system.service;

import cn.jiguang.common.resp.APIConnectionException;
import cn.jiguang.common.resp.APIRequestException;
import cn.jpush.api.JPushClient;
import cn.jpush.api.push.PushResult;
import cn.jpush.api.push.model.Message;
import cn.jpush.api.push.model.Options;
import cn.jpush.api.push.model.Platform;
import cn.jpush.api.push.model.PushPayload;
import cn.jpush.api.push.model.audience.Audience;
import cn.jpush.api.push.model.notification.AndroidNotification;
import cn.jpush.api.push.model.notification.IosNotification;
import cn.jpush.api.push.model.notification.Notification;
import cn.jpush.api.schedule.ScheduleResult;
import com.wuliu.common.utils.DictUtils;
import com.wuliu.common.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;


/**
 * 极光推送工具类
 *
 * @author realue
 * @version 1.0
 * @date 2023-10-26 16:06
 */
@Slf4j
public class JPushClientService {
    //private static final String APPKEY = "********";
    //
    //private static final String MASTERSECRET = "********";
    //
    //private static JPushClient jPushClient = new JPushClient(MASTERSECRET, APPKEY);

    private static JPushClient jPushClient;

    /**
     * 构造函数
     *
     * @param sysAccount
     */
    public JPushClientService(String sysAccount) {
        String appKey = DictUtils.getSysConfigValue(sysAccount, "jpush_app_key");
        String masterSecret = DictUtils.getSysConfigValue(sysAccount, "jpush_master_secret");
        jPushClient = new JPushClient(masterSecret, appKey);
    }

    /**
     * 发送给标识用户
     *
     * @param alias             设备标识
     * @param notificationTitle 通知内容标题
     * @param msgTitle          消息内容标题
     * @param msgContent        消息内容
     * @param extrasParam       扩展字段（传跳转的链接）
     * @param uuid              日志记录标识
     * @return false推送失败，true推送成功
     */
    public Boolean sendToAlias(List<String> alias, String notificationTitle, String msgTitle, String msgContent,
                               String extrasParam, String uuid) {
        boolean result = false;
        try {
            PushPayload pushPayload = buildPushObject(alias, notificationTitle, msgTitle, msgContent, extrasParam);
            log.info("uuid:{}, JpushUtil--sendToAlias--jpush--participation:{} ", uuid,
                    pushPayload.toJSON().toString());
            PushResult sendPush = jPushClient.sendPush(pushPayload);
            if (sendPush.getResponseCode() == 200) {
                result = true;
            }
            log.info("uuid:{}, JpushUtil--sendToAlias--jpush--outParameter:{} ", uuid, sendPush.toString());
        } catch (APIConnectionException | APIRequestException e) {
            log.error("uuid:{}, JpushUtil--sendToAlias--error:{} ", uuid, e);
        }
        return result;
    }

    /**
     * 定时发送给标识用户
     *
     * @param alias             设备标识
     * @param notificationTitle 通知内容标题
     * @param msgTitle          消息内容标题
     * @param msgContent        消息内容
     * @param extrasparam       扩展字段（传跳转的链接）
     * @param scheduleName      日程名称
     * @param scheduleTime      日程时间（格式:yyyy-MM-dd HH:mm:ss）
     * @param uuid              日志记录标识
     * @return false推送失败，true推送成功
     */
    public Boolean sendToAliasTiming(List<String> alias, String notificationTitle, String msgTitle,
                                     String msgContent, String extrasparam, String scheduleName, String scheduleTime, String uuid) {
        boolean result = false;
        try {
            PushPayload pushPayload = buildPushObject(alias, notificationTitle, msgTitle, msgContent, extrasparam);
            log.info("uuid:{}, JpushUtil--sendToAliasTiming--jpush--participation:{} ", uuid,
                    pushPayload.toJSON().toString());
            ScheduleResult createSingleSchedule = jPushClient.createSingleSchedule(scheduleName, scheduleTime,
                    pushPayload);
            if (createSingleSchedule.getResponseCode() == 200) {
                result = true;
            }
            log.info("uuid:{}, JpushUtil--sendToAliasTiming--jpush--outParameter:{} ", uuid,
                    createSingleSchedule.toString());
        } catch (APIConnectionException | APIRequestException e) {
            log.error("uuid:{}, JpushUtil--sendToAliasTiming--error:{} ", uuid, e);
        }
        return result;
    }

    /**
     * 发送给所有安卓用户
     *
     * @param notificationTitle 通知内容标题
     * @param msgTitle          消息内容标题
     * @param msgContent        消息内容
     * @param extrasparam       扩展字段（传跳转的链接）
     * @param uuid              日志记录标识
     * @return false推送失败，true推送成功
     */
    public Boolean sendToAndroid(String notificationTitle, String msgTitle, String msgContent,
                                 String extrasparam, String uuid) {
        boolean result = false;
        try {
            PushPayload pushPayload = buildPushObjectByAndroid(notificationTitle, msgTitle, msgContent, extrasparam);
            log.info("uuid:{}, JpushUtil--sendToAndroid--jpush--participation:{} ", uuid,
                    pushPayload.toJSON().toString());
            PushResult sendPush = jPushClient.sendPush(pushPayload);
            if (sendPush.getResponseCode() == 200) {
                result = true;
            }
            log.info("uuid:{}, JpushUtil--sendToAndroid--jpush--outParameter:{} ", uuid, sendPush.toString());
        } catch (APIConnectionException | APIRequestException e) {
            log.error("uuid:{}, JpushUtil--sendToAndroid--error:{} ", uuid, e);
        }
        return result;
    }

    /**
     * 发送给所有IOS用户
     *
     * @param notificationTitle 通知内容标题
     * @param msgTitle          消息内容标题
     * @param msgContent        消息内容
     * @param extrasparam       扩展字段（传跳转的链接）
     * @param uuid              日志记录标识
     * @return false推送失败，true推送成功
     */
    public Boolean sendToIos(String notificationTitle, String msgTitle, String msgContent, String extrasparam,
                             String uuid) {
        boolean result = false;
        try {
            PushPayload pushPayload = buildPushObjectByIos(notificationTitle, msgTitle, msgContent, extrasparam);
            log.info("uuid:{}, JpushUtil--sendToIos--jpush--participation:{} ", uuid, pushPayload.toJSON().toString());
            PushResult sendPush = jPushClient.sendPush(pushPayload);
            if (sendPush.getResponseCode() == 200) {
                result = true;
            }
            log.info("uuid:{}, JpushUtil--sendToIos--jpush--outParameter:{} ", uuid, sendPush.toString());
        } catch (APIConnectionException | APIRequestException e) {
            log.error("uuid:{}, JpushUtil--sendToIos--error:{} ", uuid, e);
        }
        return result;
    }

    /**
     * 发送给所有用户
     *
     * @param notificationTitle 通知内容标题
     * @param msgTitle          消息内容标题
     * @param msgContent        消息内容
     * @param extrasparam       扩展字段（传跳转的链接）
     * @param uuid              日志记录标识
     * @return false推送失败，true推送成功
     */
    public int sendToAll(String notificationTitle, String msgTitle, String msgContent, String extrasparam,
                         String uuid) {
        int result = 0;
        try {
            PushPayload pushPayload = buildPushObjectByAll(notificationTitle, msgTitle, msgContent, extrasparam);
            log.info("uuid:{}, JpushUtil--sendToAll--jpush--participation:{} ", uuid, pushPayload.toJSON().toString());
            PushResult sendPush = jPushClient.sendPush(pushPayload);
            if (sendPush.getResponseCode() == 200) {
                result = 1;
            }
            log.info("uuid:{}, JpushUtil--sendToAll--jpush--outParameter:{} ", uuid, sendPush.toString());
        } catch (APIConnectionException | APIRequestException e) {
            log.error("uuid:{}, JpushUtil--sendToAll--error:{} ", uuid, e);
        }
        return result;
    }

    /**
     * 定时发送给所有用户
     *
     * @param notificationTitle 通知内容标题
     * @param msgTitle          消息内容标题
     * @param msgContent        消息内容
     * @param extrasparam       扩展字段（传跳转的链接）
     * @param scheduleName      日程名称
     * @param scheduleTime      日程时间（格式:yyyy-MM-dd HH:mm:ss）
     * @param uuid              日志记录标识
     * @return false推送失败，true推送成功
     */
    public Boolean sendToAllTiming(String notificationTitle, String msgTitle, String msgContent,
                                   String extrasparam, String scheduleName, String scheduleTime, String uuid) {
        boolean result = false;
        try {
            PushPayload pushPayload = buildPushObjectByAll(notificationTitle, msgTitle, msgContent, extrasparam);
            log.info("uuid:{}, JpushUtil--sendToAllTiming--jpush--participation:{} ", uuid,
                    pushPayload.toJSON().toString());
            ScheduleResult createSingleSchedule = jPushClient.createSingleSchedule(scheduleName, scheduleTime,
                    pushPayload);
            if (createSingleSchedule.getResponseCode() == 200) {
                result = true;
            }
            log.info("uuid:{}, JpushUtil--sendToAllTiming--jpush--outParameter:{} ", uuid,
                    createSingleSchedule.toString());
        } catch (APIConnectionException | APIRequestException e) {
            log.error("uuid:{}, JpushUtil--sendToAllTiming--error:{} ", uuid, e);
        }
        return result;
    }

    /**
     * 组合发送对象（所有用户）
     *
     * @param notificationTitle 通知内容标题
     * @param msgTitle          消息内容标题
     * @param msgContent        消息内容
     * @param extrasparam       扩展字段（传跳转的链接）
     * @return
     */
    public PushPayload buildPushObjectByAll(String notificationTitle, String msgTitle, String msgContent,
                                            String extrasparam) {
        return PushPayload.newBuilder().setPlatform(Platform.android_ios()).setAudience(Audience.all())
                .setNotification(Notification.newBuilder().setAlert(msgContent)
                        .addPlatformNotification(AndroidNotification.newBuilder().setAlert(msgContent)
                                .setTitle(notificationTitle).addExtra("url", extrasparam).build())
                        .addPlatformNotification(IosNotification.newBuilder().setAlert(msgContent).incrBadge(1)
                                .setSound("sound.caf").addExtra("url", extrasparam).build())
                        .build())
                .setMessage(Message.newBuilder().setMsgContent(msgContent).setTitle(msgTitle)
                        .addExtra("url", extrasparam).build())
                .setOptions(Options.newBuilder().setApnsProduction(true).setSendno(1).setTimeToLive(86400).build())
                .build();
    }

    /**
     * 组合发送对象（标识用户）
     *
     * @param alias             用户标识
     * @param notificationTitle 通知内容标题
     * @param msgTitle          消息内容标题
     * @param msgContent        消息内容
     * @param extrasparam       扩展字段（传跳转的链接）
     * @return
     */
    private PushPayload buildPushObject(List<String> alias, String notificationTitle, String msgTitle,
                                        String msgContent, String extrasparam) {
        return PushPayload.newBuilder().setPlatform(Platform.all()).setAudience(Audience.alias(alias))
                .setNotification(Notification.newBuilder()
                        .addPlatformNotification(AndroidNotification.newBuilder().setAlert(msgContent)
                                .setTitle(notificationTitle).addExtra("url", extrasparam).build())
                        .addPlatformNotification(IosNotification.newBuilder().setAlert(msgContent).incrBadge(1)
                                .setSound("sound.caf").addExtra("url", extrasparam).build())
                        .build())
                .setMessage(Message.newBuilder().setMsgContent(msgContent).setTitle(msgTitle)
                        .addExtra("url", extrasparam).build())
                .setOptions(Options.newBuilder().setApnsProduction(true).setSendno(1).setTimeToLive(86400).build())
                .build();

    }

    /**
     * 组合发送对象（Android用户）
     *
     * @param notificationTitle 通知内容标题
     * @param msgTitle          消息内容标题
     * @param msgContent        消息内容
     * @param extrasparam       扩展字段（传跳转的链接）
     * @return
     */
    private PushPayload buildPushObjectByAndroid(String notificationTitle, String msgTitle, String msgContent,
                                                 String extrasparam) {
        return PushPayload.newBuilder().setPlatform(Platform.android()).setAudience(Audience.all())
                .setNotification(Notification.newBuilder()
                        .addPlatformNotification(AndroidNotification.newBuilder().setAlert(msgContent)
                                .setTitle(notificationTitle).addExtra("url", extrasparam).build())
                        .build())
                .setMessage(Message.newBuilder().setMsgContent(msgContent).setTitle(msgTitle)
                        .addExtra("url", extrasparam).build())
                .setOptions(Options.newBuilder().setApnsProduction(true).setSendno(1).setTimeToLive(86400).build())
                .build();
    }

    /**
     * 组合发送对象（ios用户）
     *
     * @param notificationTitle 通知内容标题
     * @param msgTitle          消息内容标题
     * @param msgContent        消息内容
     * @param extrasparam       扩展字段（传跳转的链接）
     * @return
     */
    private PushPayload buildPushObjectByIos(String notificationTitle, String msgTitle, String msgContent,
                                             String extrasparam) {
        return PushPayload.newBuilder().setPlatform(Platform.ios()).setAudience(Audience.all())
                .setNotification(Notification.newBuilder()
                        .addPlatformNotification(IosNotification.newBuilder().setAlert(msgContent).incrBadge(1)
                                .setSound("sound.caf").addExtra("url", extrasparam).build())
                        .build())
                .setMessage(Message.newBuilder().setMsgContent(msgContent).setTitle(msgTitle)
                        .addExtra("url", extrasparam).build())
                .setOptions(Options.newBuilder().setApnsProduction(true).setSendno(1).setTimeToLive(86400).build())
                .build();
    }

    /**
     * 校验别名是否存在
     *
     * @param alias
     * @return
     */
    private List<String> checkAlias(List<String> alias) {
        List<String> retStr = new ArrayList<>();
        try {
            for (String str : alias) {
                List<String> idsList = jPushClient.getAliasDeviceList(str, null).registration_ids;
                if (StringUtils.isNotEmpty(idsList))
                    retStr.add(str);
                else
                    log.error("[{}]别名不存在或未注册", str);
            }
            return retStr;
        } catch (APIConnectionException | APIRequestException e) {
            log.error("checkAlias--error:{} ", e.getMessage());
        }
        return retStr;
    }
}
